package tripx.db;

import java.net.MalformedURLException;
import java.net.URL;
import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;

import tripx.system.Logger;

/**
 * the <code><b>DbServiceInvoker</b></code> which send request to the database
 * server.
 * 
 * @author zhb
 * 
 */
public class DbServiceInvoker {

	private XmlRpcClient client;

	private Logger logger = Logger.getInstance();

	public DbServiceInvoker(String dbServerAddr) {
		// setup the invoker
		XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
		try {
			config.setServerURL(new URL(dbServerAddr));
		} catch (MalformedURLException e) {
			logger.err("Database server not available");
		}
		client = new XmlRpcClient();
		client.setConfig(config);
	}

	/**
	 * execute an update sql
	 * 
	 * @param sql
	 * @return rows affected
	 */
	public int executeUpdateSql(String sql) {
		Object[] params = new Object[] { sql };
		return getInteger("DbService.executeUpdateSql", params);
	}

	/**
	 * execute a query sql
	 * 
	 * @param sql
	 * @return result(json format)
	 */
	public String executeQuerySql(String sql) {
		Object[] params = new Object[] { sql };
		return getString("DbService.executeQuerySql", params);
	}

	/**
	 * add a PreparedStatement.
	 * 
	 * @param sql
	 * @param key
	 * @return status, 0 == failed, 1 == success
	 */
	public int addPrepareSql(String sql, String key) {
		Object[] params = new Object[] { sql, key };
		return getInteger("DbService.addPrepareSql", params);
	}

	/**
	 * execute an update sql, the sql is already in the PreparedStatement.
	 * 
	 * @param key
	 *            specify the statement to be executed
	 * @param placeHolderValues
	 * @return rows affected
	 */
	public int executeUpdateSql(String key, Object[] placeHolderValues) {
		Object[] params = new Object[] { key, placeHolderValues };
		return getInteger("DbService.executeUpdateSql", params);
	}

	/**
	 * execute the query sql, the sql is already in the PreparedStatement
	 * 
	 * @param key
	 *            specify the statment to be executed
	 * @param placeHolderValues
	 * @return result(json format)
	 */
	public String executeQuerySql(String key, String[] placeHolderValues) {
		Object[] params = new Object[] { key, placeHolderValues };
		return getString("DbService.executeQuerySql", params);
	}

	/**
	 * Check whether Database Service has added the given key which tells the
	 * PreparedStatement
	 * 
	 * @param key
	 * @return
	 */
	public boolean prepareKeyExist(String key) {
		try {
			return (Boolean) client.execute("DbService.prepareKeyExist",
					new Object[] { key });
		} catch (XmlRpcException e) {
			return false;
		}
	}

	/**
	 * connect to the dbServer, given the method name and the parameters, and
	 * return an Integer value
	 * 
	 * @param methodName
	 * @param params
	 * @return
	 */
	private int getInteger(String methodName, Object[] params) {
		int intValue = 0;
		try {
			intValue = (Integer) client.execute(methodName, params);
		} catch (XmlRpcException e) {

		}
		return intValue;
	}

	/**
	 * connect to the dbserver, given the method name and the parameters, return
	 * a string value.
	 * 
	 * @param methodName
	 * @param params
	 * @return
	 */
	private String getString(String methodName, Object[] params) {
		String result = "[]";
		try {
			result = (String) client.execute(methodName, params);
		} catch (XmlRpcException e) {

		}
		return result;
	}
}
